#pragma once

#include "rpc_defines.h"
#include <cstdint>
#include <string>

namespace rpc {

/**
 * @brief Address
 */
struct Address {
  std::string ip;       ///< IP
  std::int32_t port{0}; ///< port
};

extern Address NullAddress;

// User implemented interface
class Transport {
  /**
   * Global index for proxy client, It's a UUID in whole cluster
   */
  GlobalIndex globalIndex_{INVALID_GLOBAL_INDEX};

public:
  virtual ~Transport() {}
  // Send data
  // @param data The data need to send
  // @param size data size in byte
  // @return How many bytes sent, <= 0 means error
  virtual int send(const char *data, const int size) = 0;
  // Copy data from stream but doesn't remove it
  // @param [OUT] data The data need to copy
  // @param size data size in byte
  // @return How many bytes need to copy, <= 0 means error
  virtual int peek(char *data, const int size) = 0;
  // Receive data
  // Copy data from stream and remove them
  // @param [OUT] data The data need to move
  // @param size The data size in byte
  // @return How many bytes need to move, <= 0 means error
  virtual int recv(char *data, const int size) = 0;
  // Ignore some bytes in stream
  // @param size The data size in byte need to ignore
  virtual int skip(const int size) = 0;
  // Returns how many bytes in stream
  virtual int size() = 0;
  // Check whether stream has been closed
  virtual bool isClose() = 0;
  // Close stream
  virtual void close() = 0;

public:
  /**
   * @brief Get local address of transport
   * @return Address instance
   */
  virtual const Address& getLocalAddress() { return NullAddress; }
  /**
   * @brief Get remote peer address of transport
   * @return Address instance
   */
  virtual const Address& getPeerAddress() { return NullAddress; }
  // Setup global index
  // @param globalIndex global index for proxy client
  void setGlobalIndex(GlobalIndex globalIndex) { globalIndex_ = globalIndex; }
  // Returns global index
  // @return global index for proxy client
  GlobalIndex getGlobalIndex() { return globalIndex_; }
};

} // namespace rpc
